package org.kymjs.kjframe.demo;

import android.content.Context;
import android.content.Intent;
import android.media.projection.MediaProjection;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Process;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.OrientationEventListener;
import android.view.Surface;
import android.view.WindowManager;

import org.json.JSONException;
import org.json.JSONObject;
import org.webrtc.DefaultVideoDecoderFactory;
import org.webrtc.DefaultVideoEncoderFactory;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
import org.webrtc.PeerConnection;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.RTCStats;
import org.webrtc.RtpParameters;
import org.webrtc.RtpSender;
import org.webrtc.ScreenCapturerAndroid;
import org.webrtc.SessionDescription;
import org.webrtc.SurfaceTextureHelper;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoFrame;
import org.webrtc.VideoSink;
import org.webrtc.VideoSource;
import org.webrtc.VideoTrack;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class WebRtcManager {
    private static final String TAG = WebRtcManager.class.getSimpleName();
    private static final int FRAMES_PER_SECOND = 20;
    private static final int targetWidth = 980;
    private static final int targetHeight = 640;
    private static final String SDP_PARAM = "sdp";
    private static final String ICE_PARAM = "ice";

    private int realWidth;
    private int realHeight;
    private VideoCapturer videoCapturer;
    private EglBase rootEglBase;
    private PeerConnectionFactory peerConnectionFactory;
    private VideoTrack localVideoTrack;
    private PeerConnection localPeer = null;
    private MediaConstraints sdpConstraints;
    private SignalClient client;
    private OrientationEventListener orientationListener;
    private int lastRotation = -1;

    List<PeerConnection.IceServer> peerIceServers = new ArrayList<>();
    private List<IceServer> iceServers = null;

    private Display display;
    private DisplayMetrics screenMetrics = new DisplayMetrics();
    private Handler handler = new Handler(Looper.getMainLooper());
    private Runnable rotationChecker;
    private Thread rotationDetectorThread = null;
    private Boolean isSdpSet = false;
    private List<IceCandidate> pendingCandidates = new ArrayList<>();

    public WebRtcManager(Intent intent, Context context, SignalClient client) {
        this.client = client;
//        this.server = server;
        WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        display = wm.getDefaultDisplay();

        createMediaProjection(intent);
        initWebRTC(context, intent);
    }

    public void close() {
        stop();
        stopRotationDetector();
        destroyMediaProjection();
    }

    private void createMediaProjection(Intent intent) {
        videoCapturer = new ScreenCapturerAndroid(intent,
                new MediaProjection.Callback() {
                    @Override
                    public void onStop() {
                        super.onStop();
                        Log.e(TAG, "User has revoked media projection permissions");
                    }
                });
    }

    private void destroyMediaProjection() {
        try {
            videoCapturer.stopCapture();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return;
        }
        videoCapturer = null;
    }

    private void initWebRTC(Context context, Intent mediaProjectionPermissionData) {
        // 1. 创建 Egl 上下文
        rootEglBase = EglBase.create();

        // 2. 初始化 PeerConnectionFactory
        PeerConnectionFactory.InitializationOptions options =
                PeerConnectionFactory.InitializationOptions.builder(context)
                        .setEnableInternalTracer(true)
                        .createInitializationOptions();
        PeerConnectionFactory.initialize(options);

        PeerConnectionFactory.Options factoryOptions = new PeerConnectionFactory.Options();
        peerConnectionFactory = PeerConnectionFactory.builder()
                .setOptions(factoryOptions)
                .setVideoDecoderFactory(new DefaultVideoDecoderFactory(rootEglBase.getEglBaseContext()))
                .setVideoEncoderFactory(new DefaultVideoEncoderFactory(
                        rootEglBase.getEglBaseContext(),
                        /* enableIntelVp8Encoder= */ true,
                        /* enableH264HighProfile= */ true))
                .createPeerConnectionFactory();


        // 3. 初始化屏幕采集器 ScreenCapturerAndroid（你传入的 permission intent）
        videoCapturer = new ScreenCapturerAndroid(
                mediaProjectionPermissionData,
                new MediaProjection.Callback() {
                    @Override
                    public void onStop() {
                        Log.d("WebRTC", "⚠️ MediaProjection 已被用户关闭");
                    }
                });
        HandlerThread thread = new HandlerThread("WebRTC-Capture-Thread", Process.THREAD_PRIORITY_URGENT_DISPLAY);
        thread.start();

        // ✅ 不需要 setHandler，SurfaceTextureHelper 内部会自动绑定当前线程的 Looper
        SurfaceTextureHelper surfaceTextureHelper = SurfaceTextureHelper.create(
                thread.getName(), rootEglBase.getEglBaseContext());

        // 5. 创建视频源并初始化采集器
        VideoSource videoSource = peerConnectionFactory.createVideoSource(videoCapturer.isScreencast());
        videoCapturer.initialize(surfaceTextureHelper, context, videoSource.getCapturerObserver());

        // 6. 启动采集器（屏幕采集帧率和分辨率）
        videoCapturer.startCapture(targetWidth, targetHeight, FRAMES_PER_SECOND);
        // 7. 创建 VideoTrack（推流时会绑定）
        localVideoTrack = peerConnectionFactory.createVideoTrack("ARDAMSv0", videoSource);
        localVideoTrack.addSink(new VideoSink() {
            @Override
            public void onFrame(VideoFrame frame) {
//                Log.d("WebRTC", "✅ 已采集到帧: 时间戳=" + frame.getTimestampNs() +
//                        " 宽=" + frame.getBuffer().getWidth() +
//                        " 高=" + frame.getBuffer().getHeight());
            }
        });
        // 🚀 你可以现在就 addTrack(localVideoTrack) 给 peerConnection 推流
        // 或者等信令协商完后再添加
//        获取真实分辨比
        startRotationWatcher(context);
    }


    public void start() {
        Log.d(TAG, "WebRTC start");
        if (localPeer != null)return;
        createPeerConnection();
        //        doCall();
    }

    public void stop() {
        Log.d(TAG, "WebRTC stop");
        if (localPeer == null)
            return;
        localPeer.close();
        localPeer = null;
    }

    private void createPeerConnection() {
        List<PeerConnection.IceServer> iceServers = new ArrayList<>();
        iceServers.add(PeerConnection.IceServer.builder("turn:stun.zhikayun.com:3478").setUsername("admin").setPassword("123456").createIceServer());
        PeerConnection.RTCConfiguration rtcConfig =
                new PeerConnection.RTCConfiguration(iceServers);
        // TCP candidates are only useful when connecting to a server that supports
        // ICE-TCP.
        rtcConfig.tcpCandidatePolicy = PeerConnection.TcpCandidatePolicy.DISABLED;
        rtcConfig.bundlePolicy = PeerConnection.BundlePolicy.MAXBUNDLE;
        rtcConfig.rtcpMuxPolicy = PeerConnection.RtcpMuxPolicy.REQUIRE;
        rtcConfig.sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN;
        rtcConfig.continualGatheringPolicy = PeerConnection.ContinualGatheringPolicy
                .GATHER_CONTINUALLY;
        rtcConfig.keyType = PeerConnection.KeyType.ECDSA;
        localPeer = peerConnectionFactory.createPeerConnection(rtcConfig,
                new CustomPeerConnectionObserver("localPeerCreation") {
                    @Override
                    public void onIceCandidate(IceCandidate iceCandidate) {
                        super.onIceCandidate(iceCandidate);
                        onIceCandidated(iceCandidate);
                    }
                });
        // 每隔 2 秒轮询 stats
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                if (localPeer != null) {
                    localPeer.getStats(report -> {
                        for (RTCStats stats : report.getStatsMap().values()) {
                            if ("outbound-rtp".equals(stats.getType())) {
                                Object bitrate = stats.getMembers().get("bytesSent");
                                Object frameRate = stats.getMembers().get("framesPerSecond"); // 某些版本支持
                                Log.d(TAG, "🚀 推送中: bytesSent=" + bitrate + ", 帧率=" + frameRate);
                            }
                        }
                    });
                }
            }
        }, 2000, 1000); // 初始延迟 2 秒，每 2 秒执行一次

        addTrackToLocalPeer();
    }
    private void addTrackToLocalPeer() {
        List<String> mediaStreamLabels = Collections.singletonList("ARDAMS");
        RtpSender sender = localPeer.addTrack(localVideoTrack, mediaStreamLabels);

        if (sender != null) {
            RtpParameters parameters = sender.getParameters();
            if (!parameters.encodings.isEmpty()) {
                RtpParameters.Encoding encoding = parameters.encodings.get(0);
                encoding.maxBitrateBps = 800_000;
                encoding.minBitrateBps = 400_000;  // 可选
                encoding.maxFramerate = 20;        // 可选
                encoding.active = true;
                sender.setParameters(parameters);
                Log.d(TAG, "✅ 成功设置编码器参数");
            }
        }
    }

    public void onIceCandidated(IceCandidate iceCandidate) {
        JSONObject messageJson = new JSONObject();
        JSONObject iceJson = new JSONObject();
        try {
            iceJson.put("type", "candidate");
            iceJson.put("sdpMid", iceCandidate.sdpMid);
            iceJson.put("sdpMLineIndex", iceCandidate.sdpMLineIndex);
            iceJson.put("candidate", iceCandidate.sdp);

            messageJson.put("type", "ice");
            messageJson.put("data", iceJson);

            String messageJsonStr = messageJson.toString();
            //XXX broadcast
            client.send(messageJsonStr);
            Log.d(TAG, "Send ICE candidates: " + messageJsonStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void onOfferReceived(JSONObject data) {
        System.out.println("Received Offer: " + data.toString());
//        handleScreenRotation(0);
        // 1. 设置远端 SDP（offer）
        SessionDescription offer = new SessionDescription(
                SessionDescription.Type.fromCanonicalForm(data.optString("type")),
                data.optString("sdp")
        );

        localPeer.setRemoteDescription(new CustomSdpObserver("remoteSetRemoteDesc"), offer);

        // 2. 准备回复的 SDP answer
        sdpConstraints = new MediaConstraints();
        sdpConstraints.mandatory.add(
                new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true")
        );

        // 3. 生成 answer
        localPeer.createAnswer(new CustomSdpObserver("localCreateAnswer") {
            @Override
            public void onCreateSuccess(SessionDescription sessionDescription) {
                super.onCreateSuccess(sessionDescription);

                // 设置本地 SDP（answer）
                localPeer.setLocalDescription(new CustomSdpObserver("localSetLocalDesc"){
                    @Override
                    public void onSetSuccess() {
                        super.onSetSuccess();
                        isSdpSet = true;
                        for (IceCandidate candidate : pendingCandidates) {
                            System.out.println("添加candidate结果："+localPeer.addIceCandidate(candidate));
                        }
                        pendingCandidates.clear();
                    }
                }, sessionDescription);
                // 4. 发送 answer 给对方
                JSONObject answerJson = new JSONObject();
                JSONObject sdpJson = new JSONObject();
                try {
                    sdpJson.put("type", sessionDescription.type.canonicalForm());
                    sdpJson.put("sdp", sessionDescription.description);

                    answerJson.put("type", "sdp");
                    answerJson.put("data", sdpJson);
                } catch (JSONException e) {
                    e.printStackTrace();
                    return;
                }

                String messageJsonStr = answerJson.toString();
                client.send(messageJsonStr);
                Log.d(TAG, "Send SDP answer: " + messageJsonStr);

            }
        }, sdpConstraints);
    }
    public void onIceCandidateReceived(JSONObject data) {
        Log.d(TAG, "ICE candidate received: " + data.toString());

        try {
            String sdpMid = data.getString("sdpMid");             // e.g. "0"
            int sdpMLineIndex = data.getInt("sdpMLineIndex");     // e.g. 0
            String candidate = data.getString("candidate");       // candidate 字符串

            IceCandidate iceCandidate = new IceCandidate(sdpMid, sdpMLineIndex, candidate);

            if (isSdpSet) {
                System.out.println("添加candidate结果："+localPeer.addIceCandidate(iceCandidate));
            } else {
                pendingCandidates.add(iceCandidate);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    public void startRotationWatcher(Context context) {
        final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        final Display display = wm.getDefaultDisplay();

        rotationChecker = new Runnable() {
            @Override
            public void run() {
                int rotation = display.getRotation();
                if (rotation != lastRotation) {
                    lastRotation = rotation;
                    handleScreenRotation(rotation);
                }

                // 每 500ms 检查一次（可调）
                handler.postDelayed(this, 500);
            }
        };

        // 启动轮询
        rotationChecker.run();
    }

    private void handleScreenRotation(int orientation){
        if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) return;

        int currentRotation = display.getRotation();
            display.getRealMetrics(screenMetrics);
            realHeight = screenMetrics.heightPixels;
            realWidth = screenMetrics.widthPixels;
            lastRotation = currentRotation;

            Log.d(TAG, "📱 屏幕旋转，方向变更为：" + currentRotation);

            // 只通知远端方向，不重启采集
            JSONObject answerJson = new JSONObject();
            JSONObject screenJson = new JSONObject();
            try {
                screenJson.put("rotation", currentRotation);
                screenJson.put("width", realWidth);
                screenJson.put("height", realHeight);
                answerJson.put("type", "orientation");
                answerJson.put("data", screenJson);
                client.send(answerJson.toString());
            } catch (JSONException e) {
                e.printStackTrace();
            }
    }

    private void stopRotationDetector() {
        if (rotationDetectorThread != null && rotationDetectorThread.isAlive()) {
            rotationDetectorThread.interrupt();
        }
    }
 }
